<template>
  <div class="main-container">
    <!-- 地图容器 -->
    <div class="maps-container">
      <div class="map-wrapper">
        <label class="custom-file-upload">
          请导入osm的zip文件
          <input type="file" @change="event => handleFileChange(0, event)" accept=".zip" />
        </label>
        <span v-if="fileNames[0]">文件名: {{ fileNames[0] }}</span>
        <div id="map1" ref="map1"></div>
      </div>
      <div class="map-wrapper">
        <label class="custom-file-upload">
          请导入草图的zip文件
          <input type="file" @change="event => handleFileChange(1, event)" accept=".zip" />
        </label>
        <span v-if="fileNames[1]">文件名: {{ fileNames[1] }}</span>
        <div id="map2" ref="map2"></div>
      </div>
    </div>
  </div>

  <v-row class="data-container">
    <!-- 第一个数据框 -->
    <v-col cols="6">
      <v-card class="data-box">
        <v-toolbar flat dense height="32" class="toolbar-small" color="grey lighten-4">
          <v-toolbar-title class="text-subtitle-2">
            相似度匹配结果
            <v-btn small color="primary" class="ml-2" @click="fetchArrayData('getPartSim', selectedValue, selectedOsmValue, 0)">局部匹配</v-btn>
          </v-toolbar-title>
        </v-toolbar>

        <v-card-text>
          <v-list dense>
            <v-list-item v-for="(item, index) in currentItems" :key="index">
              <v-list-item-content>
                <!-- 显示 Sim 值和数组 -->
                Sim值为: {{ item.similarity.toFixed(2) }}, 相似度结果: {{ item.resultArray.join(', ') }}
                <v-btn small color="primary" class="ml-2" @click="handleButtonClick(item.resultArray)">
                  第{{index}}个结果
                </v-btn>
              </v-list-item-content>
            </v-list-item>
          </v-list>

          <v-card-actions>
            <v-btn small :disabled="currentPage === 1" @click="prevPage">上一页</v-btn>
            <v-spacer></v-spacer>
            <span>第 {{ currentPage }} 页</span>
            <v-spacer></v-spacer>
            <v-btn small :disabled="currentPage === totalPages" @click="nextPage">下一页</v-btn>
          </v-card-actions>
        </v-card-text>
      </v-card>
    </v-col>

    <!-- 第二个数据框 -->
    <v-col cols="6">
      <v-card class="data-box">
        <v-toolbar flat dense height="32" class="toolbar-small" color="grey lighten-4">
          <v-toolbar-title class="text-subtitle-2">
            相似度匹配结果
            <v-btn small color="primary" class="ml-2" @click="fetchArrayData('OverAll', selectedValue, selectedOsmValue, 1)">全局匹配</v-btn>
          </v-toolbar-title>
        </v-toolbar>

        <v-card-text>
          <v-list dense>
            <v-list-item v-for="(item, index) in otherCurrentItems" :key="index">
              <v-list-item-content>
                <!-- 显示 Sim 值和数组 -->
                Sim值为: {{ item.similarity.toFixed(2) }}, 相似度结果: {{ item.resultArray.join(', ') }}
                <v-btn small color="primary" class="ml-2" @click="handleButtonClick(item.resultArray)">
                  点击这里
                </v-btn>
              </v-list-item-content>
            </v-list-item>
          </v-list>

          <v-card-actions>
            <v-btn small :disabled="otherCurrentPage === 1" @click="prevOtherPage">上一页</v-btn>
            <v-spacer></v-spacer>
            <span>第 {{ otherCurrentPage }} 页</span>
            <v-spacer></v-spacer>
            <v-btn small :disabled="otherCurrentPage === otherTotalPages" @click="nextOtherPage">下一页</v-btn>
          </v-card-actions>
        </v-card-text>
      </v-card>
    </v-col>
  </v-row>
</template>

<script>
import { ref, onMounted, computed } from 'vue';
import L from 'leaflet';
import shp from 'shpjs'; // 确保安装了 shpjs
import 'leaflet/dist/leaflet.css';
import { spring1, spring2 } from '@/linux';

// 使用 import 语法引入 Leaflet 默认图标
import markerIcon from 'leaflet/dist/images/marker-icon.png';
import markerShadow from 'leaflet/dist/images/marker-shadow.png';
import markerIcon2x from 'leaflet/dist/images/marker-icon-2x.png';

// Leaflet 默认图标样式
delete L.Icon.Default.prototype._getIconUrl;
L.Icon.Default.mergeOptions({
  iconRetinaUrl: markerIcon2x,
  iconUrl: markerIcon,
  shadowUrl: markerShadow,
});

export default {
  name: "Customize",
  setup() {
    const mapInstances = ref([null, null]); // 用于存储多个地图实例
    const geojsonLayers = ref([null, null]); // 用于存储多个 GeoJSON 图层
    const arrayData = ref([[], []]); // 用于存储两个数据框的数组数据
    const currentPage = ref(1); // 当前页
    const otherCurrentPage = ref(1); // 另一个数据框的当前页
    const itemsPerPage = 5; // 每页显示的项目数
    const fileNames = ref(["", ""]); // 用于存储文件名

    const selectedValue = ref(""); // 默认选择的值
    const selectedOsmValue = ref(""); // 可选项列表

    onMounted(() => {
      // 创建两个地图实例
      mapInstances.value[0] = L.map('map1').setView([0, 0], 2); // 第一个地图
      mapInstances.value[1] = L.map('map2').setView([0, 0], 2); // 第二个地图
    });

    const fetchArrayData = async (end, caoTu, osm, index) => {
      try {
        const response = await fetch(`${spring2}/data/${end}?caoTuLabel=${caoTu}Group&realLabel=${osm}Group`);
        if (!response.ok) {
          throw new Error('网络响应不是 OK');
        }
        const result = await response.json(); // 假设返回的是 JSON 格式的数组
        arrayData.value[index] = result.data; // 将获取的数据填充到对应的数组中
      } catch (error) {
        console.error('获取数组数据时出错:', error);
      }
    };

    const totalPages = computed(() => Math.ceil(arrayData.value[0].length / itemsPerPage));
    const otherTotalPages = computed(() => Math.ceil(arrayData.value[1].length / itemsPerPage));

    const currentItems = computed(() => {
      const start = (currentPage.value - 1) * itemsPerPage;
      return arrayData.value[0].slice(start, start + itemsPerPage);
    });

    const otherCurrentItems = computed(() => {
      const start = (otherCurrentPage.value - 1) * itemsPerPage;
      return arrayData.value[1].slice(start, start + itemsPerPage);
    });

    const handleButtonClick = (resultArray) => {
      resetHighlight(); // 清除之前的高亮
      resultArray.forEach((itemKey) => {
        highlightSpecificFeature(0, itemKey); // 调用高亮函数
      });
    };

    const prevPage = () => { if (currentPage.value > 1) currentPage.value--; };
    const nextPage = () => { if (currentPage.value < totalPages.value) currentPage.value++; };
    const prevOtherPage = () => { if (otherCurrentPage.value > 1) otherCurrentPage.value--; };
    const nextOtherPage = () => { if (otherCurrentPage.value < otherTotalPages.value) otherCurrentPage.value++; };

    const handleFileChange = (index, event) => {
      const file = event.target.files[0];
      if (file) {
        fileNames.value[index] = file.name;
        uploadFile(file, index); // 传递 index
        loadShpZip(index, file);
      }
    };

    // 主函数：处理文件上传和 Neo4j 处理
    const uploadFile = async (file, index) => {
      try {
        // 上传文件并获取返回的文件路径
        const shpFileUrls = await uploadFileToServer(file);
        console.log('shp文件下载地址:', shpFileUrls);

        // 将文件路径发送到 Neo4j 接口
        const result = await sendFileToNeo4j(shpFileUrls,index);

        // 根据 index 更新 selectedValue 或 selectedOsmValue
        if (index === 0) {
          selectedOsmValue.value = result.data; // 更新 selectedOsmValue
        } else if (index === 1) {
          selectedValue.value = result.data; // 更新 selectedValue
        }

        console.log('Neo4j处理结果:', result);
      } catch (err) {
        console.error('Error:', err);
        alert('操作失败');
      }
    };

    // 上传文件到服务器
    const uploadFileToServer = async (file) => {
      const formData = new FormData();
      formData.append('file', file);

      const response = await fetch('http://localhost:9091/file/upload', {
        method: 'POST',
        body: formData,
      });

      if (!response.ok) {
        throw new Error('File upload failed');
      }

      const result = await response.json();
      console.log('File uploaded:', result.data);
      alert('文件上传成功');
      return result.data; // 返回文件下载地址
    };

// 将文件路径发送到 Neo4j 接口
    const sendFileToNeo4j = async (fileUrl,index) => {
      const response = await fetch('http://localhost:9090/file/initNeo4j'+"?index="+index, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ fileUrl }),
      });

      if (!response.ok) {
        throw new Error('处理neo4j失败');
      }

      const result = await response.json();
      console.log('Neo4j处理结果:', result);
      alert('Neo4j处理成功');
      return result;
    };


    const loadShpZip = (index, fileOrMapName) => {
      let fileInput = null;
      let file = null;

      if (geojsonLayers.value[index]) {
        mapInstances.value[index].removeLayer(geojsonLayers.value[index]);
        geojsonLayers.value[index] = null;
      }

      if (typeof fileOrMapName === 'string') {
        fetchZipFromServer(index, fileOrMapName);
      } else {
        file = fileOrMapName;
        if (file && file.name.endsWith('.zip')) {
          processLocalZipFile(index, file);
        }
      }
    };

    const fetchZipFromServer = (index, mapName) => {
      fetch(`${spring1}/file/content?filename=${mapName}`)
          .then(response => {
            if (!response.ok) {
              throw new Error('网络响应不是 OK');
            }
            return response.arrayBuffer();
          })
          .then(arrayBuffer => {
            const reader = new FileReader();
            reader.onload = () => {
              processGeoJSON(index, reader.result);
            };
            reader.readAsArrayBuffer(new Blob([arrayBuffer]));
          })
          .catch(error => {
            console.error('获取后端文件时出错:', error);
          });
    };

    const processLocalZipFile = (index, file) => {
      const reader = new FileReader();
      reader.readAsArrayBuffer(file);
      reader.onload = () => {
        processGeoJSON(index, reader.result);
      };
    };

    const processGeoJSON = (index, arrayBuffer) => {
      shp(arrayBuffer)
          .then((geojson) => {
            geojsonLayers.value[index] = L.geoJSON(geojson, {
              onEachFeature: (feature, layer) => {
                layer.on({
                  mousedown: () => {
                    if (layer.options.highlighted) {
                      resetHighlight(layer);
                      layer.options.highlighted = false;
                    } else {
                      highlightFeature(layer);
                      layer.options.highlighted = true;
                    }
                  },
                });
              },
              style: {
                color: "#3388ff",
                weight: 2,
                opacity: 1,
              },
            }).addTo(mapInstances.value[index]);

            mapInstances.value[index].fitBounds(geojsonLayers.value[index].getBounds());
          })
          .catch((error) => {
            console.error('解析 GeoJSON 时出错:', error);
          });
    };

    const highlightFeature = (layer) => {
      layer.setStyle({
        weight: 5,
        color: "#ff7800",
        dashArray: '',
        fillOpacity: 0.7,
      });
    };

    const resetHighlight = (layer) => {
      geojsonLayers.value.forEach((geojsonLayer) => {
        if (geojsonLayer) {
          geojsonLayer.resetStyle(layer);
        }
      });
    };

    const highlightSpecificFeature = (index, objectId) => {
      geojsonLayers.value[index].eachLayer((layer) => {
        if (layer.feature && layer.feature.properties.OBJECTID === objectId) {
          highlightFeature(layer);
        }
      });
    };

    return {
      handleFileChange,
      uploadFile,
      loadShpZip,
      fileNames,
      arrayData,
      currentItems,
      otherCurrentItems,
      currentPage,
      otherCurrentPage,
      totalPages,
      otherTotalPages,
      handleButtonClick,
      prevPage,
      nextPage,
      prevOtherPage,
      nextOtherPage,
      fetchArrayData,
      selectedValue,
      selectedOsmValue
    };
  },
};
</script>

<style>
.main-container {
  display: flex;
  flex-direction: column;
}

.maps-container {
  display: flex;
  justify-content: space-between;
}

.map-wrapper {
  width: 48%;
}

#map1,
#map2 {
  height: 400px;
  border: 1px solid #ccc;
}

.data-container {
  margin-top: 20px;
}

.data-box {
  margin-top: 2px;
}

.custom-file-upload {
  display: inline-block;
  padding: 6px 12px;
  cursor: pointer;
  border: 1px solid #ccc;
  border-radius: 4px;
  background-color: #f8f8f8;
}

.custom-file-upload input[type="file"] {
  display: none;
}
</style>